<?php

declare (strict_types=1);

namespace app\api\controller;

use app\api\service\passport\Login as LoginService;
use app\api\model\Store as StoreModel;
use app\api\model\User as UserModel;
use app\api\service\User as UserService;
use cores\BaseController;
use cores\exception\BaseException;

/**
 * API控制器基类
 * Class Controller
 * @package app\store\controller
 */
class Controller extends BaseController
{
    // 当前平台id
    protected $storeId;

    protected $userId;

    protected $user;

    // 当前渠道id
    protected $channelId;

    // 当前控制器名称
    protected $controller = '';

    // 当前方法名称
    protected $action = '';

    // 当前路由uri
    protected $routeUri = '';

    // 当前路由：分组名称
    protected $group = '';

    // 登录验证白名单
    protected $allowAllAction = [
        'passport/login',
        'passport/logout',
        'index/config',
        'question.index/getObtainPracticeQuestions'
    ];
    /**
     * API基类初始化
     * @throws BaseException
     */
    public function initialize()
    {
        // 当前平台id
        $this->storeId = $this->getStoreId();
        // 当前用户信息
        $this->setUserInfo();
        // 验证当前平台状态
        $this->checkStore();
        // 当前路由信息
        $this->getRouteInfo();
        // 验证登录状态
        $this->checkLogin();
        // 验证当前客户端状态
        $this->checkClient();
        // 验证渠道
//        $this->checkChannel();
    }

    /**
     * 获取当前平台ID
     * @return int|null
     * @throws BaseException
     */
    protected function getStoreId(): ?int
    {
        $storeId = getStoreId();    // app/api/common.php
        empty($storeId) && throwError('缺少必要的参数：storeId');
        return $storeId;
    }

    /**
     * 设置用户登录信息
     */
    private function setUserInfo()
    {
        $this->user = LoginService::getLoginInfo();
    }

    /**
     * 验证当前平台状态
     * @return void
     * @throws BaseException
     */
    private function checkStore(): void
    {
        // 获取当前平台信息
        $store = StoreModel::detail($this->storeId);
        if (empty($store)) {
            throwError('当前平台信息不存在');
        }
        if ($store['is_recycle'] || $store['is_delete']) {
            throwError('当前平台已删除');
        }
    }

    /**
     * 验证登录状态
     * @return bool
     * @throws BaseException
     */
    private function checkLogin(): bool
    {
        // 验证当前请求是否在白名单
        if (in_array($this->routeUri, $this->allowAllAction)) {
            return true;
        }
        // 验证登录状态
        if (empty($this->user)) {
            throwError('请先登录后再访问', config('status.not_logged'));
        }
        return true;
    }


    /**
     * 验证当前客户端是否允许访问
     * @throws BaseException
     */
    private function checkClient()
    {
        $client = getPlatform();
        $settingClass = [
            'H5' => [\app\api\model\h5\Setting::class, 'checkStatus', 'H5端']
        ];
        if (!isset($settingClass[$client])) {
            return;
        }
        $status = call_user_func([$settingClass[$client][0], $settingClass[$client][1]]);
        $status === false && throwError('很抱歉，当前' . $settingClass[$client][2] . '端暂不支持访问');
    }

    /**
     * 解析当前路由参数 （分组名称、控制器名称、方法名）
     */
    protected function getRouteInfo()
    {
        // 控制器名称
        $this->controller = uncamelize($this->request->controller());
        // 方法名称
        $this->action = $this->request->action();
        // 控制器分组 (用于定义所属模块)
        $group = strstr($this->controller, '.', true);
        $this->group = $group !== false ? $group : $this->controller;
        // 当前uri
        $this->routeUri = "{$this->controller}/$this->action";
    }

    protected function checkChannel()
    {
        $data = $this->request->param();
        $allowAllAction = [
            'upload/image',
        ];
        if (!in_array($this->routeUri, $allowAllAction)) {
            $channel_id = $this->request->header('Channelid');
            if (!$channel_id) {
                throwError('请扫码进行考试！');
            }
            $channel = (new \app\common\model\store\User())->where([
                'store_user_id' => $channel_id,
                'is_delete' => 0,
            ])->find();
            if (!$channel) {
                throwError('当前二维码已失效！请联系对应机构，获取最新二维码');
            }
            $this->channelId = $channel_id;
        }

    }

    /**
     * 获取当前用户信息
     * @param bool $isForce 强制验证登录
     * @return UserModel|bool|null
     * @throws BaseException
     */
    protected function getLoginUser(bool $isForce = true)
    {
        return UserService::getCurrentLoginUser($isForce);
    }
}
